//jewels
freeslot("SPR_FCJW", "MT_JEWEL", "MT_ORANGEJEWEL", "MT_BIGJEWEL", "S_JEWEL", "S_ORANGEJEWEL", "S_BIGJEWEL", "sfx_fcjew1", "sfx_fcjew2", "sfx_fcjew3", "sfx_fcglas")

mobjinfo[MT_JEWEL] = {
	//$Name Jewel
	//$Sprite FCJWA0
	doomednum = 3012,
	spawnstate = S_JEWEL,
	spawnhealth = 9999999,
	deathstate = S_SPRK1,
	flags = MF_NOGRAVITY|MF_SPECIAL,
	radius = 16*FRACUNIT,
	height = 64*FRACUNIT,
	deathsound = sfx_fcjew1
}

mobjinfo[MT_ORANGEJEWEL] = {
	//$Name Orange Jewel
	//$Sprite FCJWB0
	doomednum = 3013,
	spawnstate = S_ORANGEJEWEL,
	spawnhealth = 9999999,
	deathstate = S_SPRK1,
	flags = MF_NOGRAVITY|MF_SPECIAL,
	radius = 16*FRACUNIT,
	height = 64*FRACUNIT,
	deathsound = sfx_fcjew2
}

mobjinfo[MT_BIGJEWEL] = {
	//$Name Big Jewel
	//$Sprite FCJWC0
	doomednum = 3014,
	spawnstate = S_BIGJEWEL,
	spawnhealth = 9999999,
	deathstate = S_SPRK1,
	flags = MF_NOGRAVITY|MF_SPECIAL,
	radius = 32*FRACUNIT,
	height = 64*FRACUNIT,
	deathsound = sfx_fcjew3
}

states[S_JEWEL] = {SPR_FCJW, A, -1, nil, 0, 0, S_JEWEL}

states[S_ORANGEJEWEL] = {SPR_FCJW, B, -1, nil, 0, 0, S_ORANGEJEWEL}

states[S_BIGJEWEL] = {SPR_FCJW, C, -1, nil, 0, 0, S_BIGJEWEL}

addHook("TouchSpecial", function(mobj, toucher)
	if toucher.player and not toucher.player.bot then P_GivePlayerRings(toucher.player, 1) end
end, MT_JEWEL)

addHook("TouchSpecial", function(mobj, toucher)
	if toucher.player and not toucher.player.bot then P_GivePlayerRings(toucher.player, 2) end
end, MT_ORANGEJEWEL)

addHook("TouchSpecial", function(mobj, toucher)
	if toucher.player and not toucher.player.bot then P_GivePlayerRings(toucher.player, 40) end
end, MT_BIGJEWEL)


//boxes
freeslot("MT_FLATBOX", "MT_FLATBOXSIDES", "SPR_BOXF", "SPR_BOXY", "S_BOXFLOORW", "S_BOXSIDEW", "S_BOXFLOORM", "S_BOXSIDEM", "sfx_jewbox", "sfx_fccrat", "sfx_fcbloc")

mobjinfo[MT_FLATBOX] = {
        //$Name Box
		//$Sprite BOXYA0
		//$Arg0 Metal Box?
		//$Arg0Type	11
		//$Arg0Enum	{0="No"; 1="Yes";}
		//$Arg1 Frame
		//$Arg1Type	11
		//$Arg1Enum	{0="Wood"; 1="Jewel"; 2="Metal"; 3="Glass";}
		//$Flags1Text Metal Box
		doomednum = 3011,
        spawnstate = S_BOXFLOORW,
        spawnhealth = 1,
        deathsound = sfx_None,
        speed = 1,
        radius = 64*FRACUNIT,
        height = 128*FRACUNIT,
        mass = 0,
        activesound = sfx_None,
		flags = MF_NOGRAVITY
}

mobjinfo[MT_FLATBOXSIDES] = {
		doomednum = -1,
        spawnstate = S_BOXFLOORW,
        spawnhealth = 1,
        deathsound = sfx_None,
        speed = 1,
        radius = 0*FRACUNIT,
        height = 0*FRACUNIT,
        mass = 0,
        activesound = sfx_None,
		flags = MF_NOGRAVITY
}

states[S_BOXSIDEW] = {SPR_BOXY, nil, -1, nil, 0, 0, S_BOXSIDEW}

states[S_BOXFLOORW] = {SPR_BOXF, nil, -1, nil, 0, 0, S_BOXFLOORW}

states[S_BOXSIDEM] = {SPR_BOXY, nil, -1, nil, 0, 0, S_BOXSIDEM}

states[S_BOXFLOORM] = {SPR_BOXF, nil, -1, nil, 0, 0, S_BOXFLOORM}

local function P_GiveRings(mobj, rings)
	 P_GivePlayerRings(mobj.player, rings)
	 S_StartSound(mobj, sfx_itemup)
end

local specialties = {
	[1] = {
		func = P_GiveRings,
		arg1 = 20,
		debris = S_JEWEL,
		arg2 = nil,
		sound = sfx_jewbox
	},
	[2] = {
		debris = S_ROCKCRUMBLEA,
		sound = sfx_crumbl
	},
	[3] = {
		debris = S_ROCKCRUMBLED,
		sound = sfx_fcglas
	}
}

addHook("MapThingSpawn", function(mobj, thing)
		mobj.flags = $|MF_SOLID
		mobj.flags2 = $|MF2_DONTDRAW
		mobj.boxtype = thing.args[1]
		if thing.options & MTF_EXTRA then mobj.state = S_BOXFLOORM end
		if thing.args[0] == 1 then mobj.state = S_BOXFLOORM end
		for i = 1, 4 do
		local anglin = i*ANGLE_90 + thing.angle*ANG1
		local x = P_ReturnThrustX(mobj, anglin, mobj.radius)
		local y = P_ReturnThrustY(mobj, anglin, mobj.radius)
		local boxside = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_FLATBOXSIDES)
		boxside.state = S_BOXSIDEW
		/*boxside.radius = mobj.radius
		boxside.height = mobj.height
		boxside.flags = $|(MF_NOTHINK|MF_PAPERCOLLISION|MF_SOLID)*/
		boxside.flags = $|MF_NOTHINK
		boxside.angle = anglin - ANGLE_90
		mobj["boxside"..i] = boxside
		if thing.options & MTF_EXTRA then boxside.state = S_BOXSIDEM end
		if thing.args[0] == 1 then boxside.state = S_BOXSIDEM end
		boxside.frame = FF_PAPERSPRITE|thing.args[1]
		end
		for i = 1,2 do
		local x = P_ReturnThrustX(mobj, thing.angle*ANG1, -mobj.radius)
		local y = P_ReturnThrustY(mobj, thing.angle*ANG1, -mobj.radius)
		local boxfloor = P_SpawnMobjFromMobj(mobj, x, y, (i-1)*mobj.height, MT_FLATBOXSIDES)
		mobj["boxfloor"..i] = boxfloor
		boxfloor.state = S_BOXFLOORW
		boxfloor.angle = thing.angle*ANG1
		boxfloor.flags = $|MF_NOCLIPHEIGHT
		boxfloor.renderflags = $|RF_NOSPLATBILLBOARD
		if thing.options & MTF_EXTRA then boxfloor.state = S_BOXFLOORM end
		if thing.args[0] == 1 then boxfloor.state = S_BOXFLOORM end
		boxfloor.frame = FF_FLOORSPRITE|thing.args[1]
		end
end, MT_FLATBOX)

addHook("MobjCollide", function(mobj, toucher)
	if toucher.type == MT_FLATBOXSIDES or toucher.type == MT_FLATBOX then return false end
	if toucher.player
		if (toucher.z >= mobj.z and toucher.z <= mobj.z + mobj.height)
		and (mobj.state ~= S_BOXFLOORM or toucher.player.speed > 24*FRACUNIT)
		and (toucher.player.pflags & PF_SPINNING or toucher.player.powers[pw_strong] & STR_ATTACK or toucher.player.pflags & PF_JUMPED) then
			local custom = specialties[mobj.boxtype]
			for i = 1,4 do
				local debris = P_SpawnMobjFromMobj(mobj["boxside"..i], 0, 0, mobj.height/2, MT_WOODDEBRIS)
				if custom and custom.debris
					debris.state = custom.debris
				end
				P_RemoveMobj(mobj["boxside"..i])
			end
			S_StartSound(toucher, (custom and custom.sound) or sfx_fccrat)
			if custom ~= nil and custom.func ~= nil
				custom.func(toucher, custom.arg1, custom.arg2)
			end
			mobj.boxfloor1.flags = $ &~ MF_NOGRAVITY
			mobj.boxfloor2.flags = $ &~ MF_NOGRAVITY
			mobj.boxfloor1.flags = $ &~ MF_NOCLIPHEIGHT
			mobj.boxfloor2.flags = $ &~ MF_NOCLIPHEIGHT
			mobj.boxfloor1.fuse = 3*TICRATE
			mobj.boxfloor2.fuse = 3*TICRATE
			P_AddPlayerScore(toucher.player, 50)
			P_InstaThrust(mobj.boxfloor2, toucher.angle, toucher.player.speed)
			P_RemoveMobj(mobj)
		end
	else
		if (toucher.z >= mobj.z + mobj.height - 7*FRACUNIT and toucher.z <= mobj.z + mobj.height + FRACUNIT)
			P_SetObjectMomZ(toucher, 0*FRACUNIT, false)
			if toucher.z < mobj.z + mobj.height + FRACUNIT then P_SetObjectMomZ(toucher, 1*FRACUNIT, false) end
		end
	end
end, MT_FLATBOX)

//batguys (enemies)
freeslot("MT_BATGUY", "S_BATGUY1", "S_BATGUY2", "S_BATGUY3", "S_BATGUY4", "S_BATGUY_D2", "S_BATGUY_D3", "S_BATGUY_D4", "S_BATGUY_D1", "S_BATGUYIDLE", "SPR_FCBG", "sfx_batdea")

mobjinfo[MT_BATGUY] = {
	//$Name Batguy
	//$Sprite FCBGA1
	doomednum = 2022,
	spawnstate = S_BATGUYIDLE,
	spawnhealth = 1,
	seestate = S_BATGUY1,
	deathstate = S_BATGUY_D1,
	deathsound = sfx_none,
	speed = 6,
	radius = 20*FRACUNIT,
	height = 32*FRACUNIT,
	mass = 0,
	damage = 0,
	activeSound = sfx_None,
	flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
}

states[S_BATGUYIDLE] = {SPR_FCBG, A, 5, A_Look, 0, 0, S_BATGUYIDLE}
states[S_BATGUY1] = {SPR_FCBG, B, 3, A_Chase, 0, 0, S_BATGUY2}
states[S_BATGUY2] = {SPR_FCBG, A, 3, A_Chase, 0, 0, S_BATGUY3}
states[S_BATGUY3] = {SPR_FCBG, C, 3, A_Chase, 0, 0, S_BATGUY4}
states[S_BATGUY4] = {SPR_FCBG, A, 3, A_Chase, 0, 0, S_BATGUY1}
states[S_BATGUY_D1] = {SPR_FCBG, D, 1, A_PlaySound, sfx_batdea, 0, S_BATGUY_D2}
states[S_BATGUY_D2] = {SPR_FCBG, D, 1, A_SetObjectFlags, MF_NOCLIP|MF_NOCLIPHEIGHT, 0, S_BATGUY_D3}
states[S_BATGUY_D3] = {SPR_FCBG, D, 1, A_BunnyHop, 10, 0, S_BATGUY_D4}
states[S_BATGUY_D4] = {SPR_FCBG, FF_ANIMATE|D, 52, None, 1, 3, S_NULL}

freeslot("MT_BATDUDE", "S_BATDUDE1", "S_BATDUDE2", "S_BATDUDE3", "S_BATDUDE4", "S_BATDUDE_D2", "S_BATDUDE_D3", "S_BATDUDE_D4", "S_BATDUDE_D1", "S_BATDUDEIDLE")

mobjinfo[MT_BATDUDE] = {
	//$Name Batdude
	//$Sprite FCBGF1
	doomednum = 2023,
	spawnstate = S_BATDUDEIDLE,
	spawnhealth = 1,
	seestate = S_BATDUDE1,
	deathstate = S_BATDUDE_D1,
	deathsound = sfx_none,
	speed = 8,
	radius = 20*FRACUNIT,
	height = 32*FRACUNIT,
	mass = DMG_SPIKE,
	damage = 0,
	activeSound = sfx_None,
	flags = MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE
}

states[S_BATDUDEIDLE] = {SPR_FCBG, F, 5, A_Look, 0, 0, S_BATDUDEIDLE}
states[S_BATDUDE1] = {SPR_FCBG, G, 3, A_Chase, 0, 0, S_BATDUDE2}
states[S_BATDUDE2] = {SPR_FCBG, F, 3, A_Chase, 0, 0, S_BATDUDE3}
states[S_BATDUDE3] = {SPR_FCBG, H, 3, A_Chase, 0, 0, S_BATDUDE4}
states[S_BATDUDE4] = {SPR_FCBG, F, 3, A_Chase, 0, 0, S_BATDUDE1}
states[S_BATDUDE_D1] = {SPR_FCBG, I, 1, A_PlaySound, sfx_batdea, 0, S_BATDUDE_D2}
states[S_BATDUDE_D2] = {SPR_FCBG, I, 1, A_SetObjectFlags, MF_NOCLIP|MF_NOCLIPHEIGHT, 0, S_BATDUDE_D3}
states[S_BATDUDE_D3] = {SPR_FCBG, I, 1, A_BunnyHop, 10, 0, S_BATDUDE_D4}
states[S_BATDUDE_D4] = {SPR_FCBG, FF_ANIMATE|I, 52, None, 1, 3, S_NULL}

addHook("TouchSpecial", function(mobj, toucher)
	if not toucher.player then return end
	if (P_MobjFlip(toucher)*(toucher.z - (mobj.z + mobj.height/2)) > 0)
		P_DamageMobj(toucher, mobj, mobj, 1, DMG_SPIKE)
	end
end, MT_BATDUDE)

//escape
freeslot("MT_BETTY", "SPR_FCBT", "MT_ESCAPEDOOR", "SPR_FCDR", "S_BETTYIDLE", "S_BETTYPANIC", "S_ESCAPEDOORNORMAL", "S_ESCAPEDOOROPEN")

mobjinfo[MT_BETTY] = {
	//$Name Betty
	//$Sprite FCBTA0
	doomednum = 3256,
	spawnstate = S_BETTYIDLE,
	spawnhealth = 99999,
	deathsound = sfx_none,
	radius = 20*FRACUNIT,
	height = 32*FRACUNIT,
	mass = 0,
	damage = 0,
	activeSound = sfx_None,
	flags = MF_NOGRAVITY|MF_SOLID
}

states[S_BETTYIDLE] = {SPR_FCBT, FF_ANIMATE|A, -1, nil, 1, 5, S_BETTYIDLE}
states[S_BETTYPANIC] = {SPR_FCBT, FF_ANIMATE|C, -1, nil, 3, 2, S_BETTYPANIC}

mobjinfo[MT_ESCAPEDOOR] = {
	//$Name Escape Door
	//$Sprite FCDRA0
	doomednum = 3257,
	spawnstate = S_ESCAPEDOORNORMAL,
	spawnhealth = 99999,
	deathsound = sfx_none,
	radius = 64*FRACUNIT,
	height = 128*FRACUNIT,
	mass = 0,
	damage = 0,
	activeSound = sfx_None,
	flags = MF_NOGRAVITY|MF_SOLID|MF_PAPERCOLLISION
}

states[S_ESCAPEDOORNORMAL] = {SPR_FCDR, FF_PAPERSPRITE|A, -1, nil, 0, 0, S_ESCAPEDOORNORMAL}
states[S_ESCAPEDOOROPEN] = {SPR_FCDR, FF_PAPERSPRITE|B, -1, nil, 0, 0, S_ESCAPEDOOROPEN}

local escape = false
local escapetimer = false

addHook("NetVars", function(net)
	escape = net(escape)
	escapetimer = net(escapetimer)
	if mapheaderinfo[gamemap].firechan
		mapmusname = net(mapmusname)
	end
end)

addHook("MobjThinker", function(mobj)
	if escape == false and mobj.panic
		mobj.state = S_BETTYIDLE
		mobj.panic = false
	end
	if mobj.cutscenetimer
		mobj.collider.player.pflags = $|PF_FULLSTASIS
		mobj.collider.cutscenetimer = mobj.cutscenetimer
		mobj.cutscenetimer = $ - 1
		if mobj.cutscenetimer < (5/2)*TICRATE
			mobj.collider.state = S_PLAY_PAIN
		end
		if mobj.cutscenetimer == 5/2*TICRATE
			mobj.state = S_BETTYPANIC
		end
		if mobj.cutscenetimer == 4*TICRATE - 1
			for player in players.iterate
				if player.mo ~= mobj.collider
					P_SetOrigin(player.mo, mobj.x + P_ReturnThrustX(player.mo, mobj.angle, mobj.scale*64), mobj.y + P_ReturnThrustY(player.mo, mobj.angle, mobj.scale*64), mobj.z)
				end
			end
		end
		if mobj.cutscenetimer == 1
			mobj.panic = true
			escape = true
			escapetimer = 215*TICRATE
			P_LinedefExecute(999)
			mobj.collider.cutscenetimer = nil
			mobj.cutscenetimer = nil
		end
	end
	if escape == true
		P_StartQuake(1*FRACUNIT, 5)
		escapetimer = $ - 1
		if escapetimer == 0
			for player in players.iterate do
				P_KillMobj(player.mo)
			end
			S_StopMusic()
			mapmusname =  mapheaderinfo[gamemap].musname
			escape = false
		end
	end
end, MT_BETTY)

addHook("MobjThinker", function(mobj)
	if escape == true and not mobj.panic
		mobj.state = S_ESCAPEDOOROPEN
		mobj.panic = true
	end
	if escape == false and mobj.panic
		mobj.state = S_ESCAPEDOORNORMAL
		mobj.panic = false
	end
end, MT_ESCAPEDOOR)

addHook("MobjCollide", function(mobj, collider)
	if not (collider.player and not collider.player.playerstate) then return end
	if (collider.z >= mobj.z + mobj.height - 2*FRACUNIT and collider.z <= mobj.z + mobj.height + 2*FRACUNIT) and not mobj.cutscenetimer and escape ~= true
		mobj.collider = collider
		mobj.cutscenetimer = 4*TICRATE
		mapmusname = "BLOWF"
		S_ChangeMusic("BLOWF", false)
	end
end, MT_BETTY)

addHook("MobjCollide", function(mobj, collider)
	if not collider.player then return end
	if escape == true and (collider.z >= mobj.z and collider.z <= mobj.z + mobj.height)
		for player in players.iterate do
			player.pflags = $|PF_FINISHED
		end
		S_ChangeMusic("ESCCLO", false)
		mapmusname = "ESCCLO"
		collider.alpha = 0
		mobj.state = S_ESCAPEDOORNORMAL
		escape = false
		escapetimer = 0
	end
end, MT_ESCAPEDOOR)

addHook("MapLoad", function()
	if (mapmusname == "BLOWF" or mapmusname == "ESCCLO") and mapheaderinfo[gamemap].firechan
		S_ChangeMusic(mapheaderinfo[gamemap].musname, true)
		mapmusname = mapheaderinfo[gamemap].musname
	end
	escape = false
	escapetimer = 0
end)

//for me health
local Minutes = G_TicsToMinutes
local Seconds = G_TicsToSeconds
local Milliseconds = G_TicsToMilliseconds

hud.add(function(v, player)
	if not mapheaderinfo[gamemap].firechan then return end
	if escape == true
		v.drawScaled(230*FRACUNIT, 130*FRACUNIT, FRACUNIT/2, v.cachePatch("BETTYHUD"))
		v.drawScaled(215*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FC"..(Minutes(escapetimer)%10)))
		v.drawScaled(230*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FCCOLON"))
		v.drawScaled(245*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FC"..((Seconds(escapetimer) - (Seconds(escapetimer)%10))/10)))
		v.drawScaled(260*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FC"..(Seconds(escapetimer)%10)))
		v.drawScaled(275*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FCDOT"))
		v.drawScaled(290*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FC"..((Milliseconds(escapetimer)-Milliseconds(escapetimer)%100)/100)))
		v.drawScaled(305*FRACUNIT, 160*FRACUNIT, FRACUNIT/2, v.cachePatch("FC"..((Milliseconds(escapetimer)%100-Milliseconds(escapetimer)%10)/10)))
	end
end, "game")

hud.add(function(v, player)
	if not mapheaderinfo[gamemap].firechan then return end
	if not player.mo.cutscenetimer then return end
	local timer = player.mo.cutscenetimer
	v.drawFill(0, 200 - 8*(timer/TICRATE), v.width(), 32, 31|V_SNAPTOBOTTOM|V_SNAPTOLEFT)
	v.drawFill(0, 0, v.width(), 8*(timer/TICRATE), 31|V_SNAPTOTOP|V_SNAPTOLEFT)
end, "game")